from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.contrib.auth.models import User, Group
from django.conf import settings
from flexy.sysmodel.models import *
from flexy.common.errors import *

def is_sysmodel(request):
    """function invoked by each view function to verify 
    if the logged in user is admin
    """
    if request.user.is_authenticated():
        if request.user.username == 'sysmodel' :
            return True
        else :
            logout(request)
    return False

def login_view(request):
    if request.method == 'GET':
        c = {}
        c.update(csrf(request))
        return render_to_response('sysmodel/login.html', c)
    else :
        username = request.POST['USERNAME']
        password = request.POST['PASSWORD']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/sysmodel/home/')
        return HttpResponseRedirect('/sysmodel/login/')
    
def logout_view(request):
    logout(request)
    return HttpResponseRedirect('/sysmodel/login/')
    
def home(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        MEDIA_URL = settings.MEDIA_URL
        return render_to_response('sysmodel/home.html', locals())
    
def flexyclass_home(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        flexyclasses = FlexyClass.objects.all().order_by('id')
        groups = FlexyGroup.objects.all().order_by('seq', 'id')
        fields = Field.objects.all().order_by('seq', 'id')
        MEDIA_URL = settings.MEDIA_URL
        return render_to_response('sysmodel/flexyclass/home.html', locals())
        
def flexyclass_add(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        c = {}
        c.update(csrf(request))
        c.update({'MEDIA_URL' : settings.MEDIA_URL})
        return render_to_response('sysmodel/flexyclass/add.html', c)
    elif request.method == 'POST':
        d = request.POST
        rd = FlexyClass.objects.add(d['NAME'], d['ENB'])
        if rd['rc'] == 0 :
            return HttpResponseRedirect('/sysmodel/flexyclass/home/')
        else :
            c = {}
            c.update(csrf(request))
            c.update({'MEDIA_URL' : settings.MEDIA_URL})
            c.update(rd)
            return render_to_response('sysmodel/flexyclass/add.html', c)
        
def flexyclass_update(request, class_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/update.html')
        
def group_add(request, class_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        c = {}
        c.update(csrf(request))
        c.update({'MEDIA_URL' : settings.MEDIA_URL})
        flexyclass = FlexyClass.objects.get(id=class_id)
        c.update({'flexyclass':flexyclass})
        return render_to_response('sysmodel/flexyclass/group/add.html', c)
    elif request.method == 'POST':
        d = request.POST
        rd = FlexyGroup.objects.add(d['NAME'], class_id)
        if rd['rc'] == 0 :
            return HttpResponseRedirect('/sysmodel/flexyclass/home/?#' + str(class_id))
        else :
            c = {}
            c.update(csrf(request))
            c.update({'MEDIA_URL' : settings.MEDIA_URL})
            flexyclass = FlexyClass.objects.get(id=class_id)
            c.update({'flexyclass':flexyclass})
            c.update(rd)
            return render_to_response('sysmodel/flexyclass/group/add.html', c)
        
def group_update(request, group_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/group/update.html')
        
def field_add(request, class_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    c = {}
    c.update(csrf(request))
    c.update({'MEDIA_URL' : settings.MEDIA_URL})
    flexyclass = FlexyClass.objects.get(id = class_id)
    c.update({'flexyclass' : flexyclass})
    c.update({'types' : SUPPORTED_FIELD_TYPES})
    c.update({'flexyclasses':FlexyClass.objects.filter(enb=1)})
    c.update({'fields':Field.objects.filter(enb=1, type="CHAR_UNIQ")})
    c.update({'groups':FlexyGroup.objects.filter(flexyclass=flexyclass)})
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/field/add.html', c)
    elif request.method == 'POST':
        d = request.POST
        rd = err[3][0]
        sel_field_id = None
        if d['TYPE'] == 'NTO1' or d['TYPE'] == 'NTOM' :
            if 'SEL_FIELD_ID' not in d:
                rd = err[3][9]
            else :
                sel_field_id = d['SEL_FIELD_ID']
        if 'GROUP_ID' not in d:
            rd = err[3][10]

        if rd['rc'] == 0 :
            rd = Field.objects.add(d['NAME'], d['TYPE'], d['GROUP_ID'], d['ENB'], sel_field_id)
        if rd['rc'] == 0 :
            return HttpResponseRedirect('/sysmodel/flexyclass/home/?#' + str(class_id))
        else :
            c.update(rd)
            return render_to_response('sysmodel/flexyclass/field/add.html', c)
        
def field_update(request, field_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/field/update.html')
    
def display_field_add(request, field_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    c = {}
    c.update(csrf(request))
    c.update({'MEDIA_URL' : settings.MEDIA_URL})
    parent_field = Field.objects.get(id=field_id)
    c.update({'field' : parent_field})
    c.update({'fields' : Field.objects.filter(enb=1, flexyclass=parent_field.sel_field.flexyclass)})
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/field/display_field/add.html',c)
    if request.method == 'POST':
        if 'DISPLAY_FIELD_ID' not in request.POST:
            c.update(err[7][1])
            return render_to_response('sysmodel/flexyclass/field/display_field/add.html',c)
        display_field_id= request.POST['DISPLAY_FIELD_ID']
        display_field = Field.objects.get(id=display_field_id)
        parent_field.display_fields.add(display_field);
        return HttpResponseRedirect('/sysmodel/flexyclass/home/')
    
def display_field_remove(request, parent_field_id, field_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    parent_field = Field.objects.get(id=parent_field_id) 
    display_field = Field.objects.get(id=field_id)
    parent_field.display_fields.remove(display_field);
    return HttpResponseRedirect('/sysmodel/flexyclass/home/')
    

def extra_field_add(request, field_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    c = {}
    c.update(csrf(request))
    c.update({'MEDIA_URL' : settings.MEDIA_URL})
    c.update({'field' : Field.objects.get(id=field_id)})
    c.update({'types' : NTO_SUPPORTED_FIELD_TYPES})
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/field/extra_field/add.html',c)
    if request.method == 'POST':
        d = request.POST
        parent_field = Field.objects.get(id = field_id)
        rd = Field.objects.extra_field_add(d['NAME'], d['TYPE'], d['ENB'], parent_field)
        if rd['rc'] == 0 :
            return HttpResponseRedirect('/sysmodel/flexyclass/home/?#' + str(parent_field.flexyclass.id))
        else :
            c.update(rd)
            return render_to_response('sysmodel/flexyclass/field/extra_field/add.html',c)

def extra_field_update(request, field_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/flexyclass/field/extra_field/update.html')
    
def user_home(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        c = {}
        c.update(csrf(request))
        c.update({'MEDIA_URL' : settings.MEDIA_URL})
        users = User.objects.all()
        c.update({'users' : users})
        return render_to_response('sysmodel/user/home.html', c)
    
def user_add(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    c = {}
    user = None
    c.update(csrf(request))
    c.update({'MEDIA_URL' : settings.MEDIA_URL})
    c.update({'user_groups' : Group.objects.all()})
    if request.method == 'GET':
        return render_to_response('sysmodel/user/add.html', c)
    elif request.method == 'POST':
        d = request.POST
        rd = None
        username = ' '.join(d['USERNAME'].upper().split())
        if username == "" :
            # Empty user name
            rd = err[5][1]
        elif d['PASSWORD1'] != d['PASSWORD2'] :
            #Password do not match
            rd = err[5][2]
        else :
            try :
                user = User.objects.create_user \
                    (username, '', d['PASSWORD1'])
                user.save()
                rd = err[5][0]
            except IntegrityError :
                #user already exists
                rd = err[5][3]
        if rd['rc'] == 0 :
            user.groups.clear()
            if int(d['GROUP_ID']) != -1 :
                ug = Group.objects.get(id=int(d['GROUP_ID']))
                user.groups.add(ug);
            return HttpResponseRedirect('/sysmodel/user/home/') 
        else :
            c.update(rd)
            return render_to_response('sysmodel/user/add.html', c)

def user_update(request, class_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/user/update.html')

def user_group_home(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        c = {}
        c.update(csrf(request))
        c.update({'MEDIA_URL' : settings.MEDIA_URL})
        groups = Group.objects.all()
        c.update({'groups' : groups})
        return render_to_response('sysmodel/usergroup/home.html', c)
    
def user_group_add(request):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    c = {}
    c.update(csrf(request))
    c.update({'MEDIA_URL' : settings.MEDIA_URL})
    if request.method == 'GET':
        return render_to_response('sysmodel/usergroup/add.html', c)
    elif request.method == 'POST':
        d = request.POST
        rd = None
        name = ' '.join(d['NAME'].upper().split())
        if name == "" :
            # Empty user group name
            rd = err[9][1]
        else :
            try :
                group = Group(name=name).save()
                rd = err[9][0]
            except IntegrityError :
                #user group already exists
                rd = err[9][2]
        if rd['rc'] == 0 :
            return HttpResponseRedirect('/sysmodel/usergroup/home/') 
        else :
            c.update(rd)
            return render_to_response('sysmodel/usergroup/add.html', c)

def user_group_update(request, class_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        return render_to_response('sysmodel/usergroup/update.html')

def user_group_view(request, user_group_id):
    if is_sysmodel(request) == False :
        return HttpResponseRedirect('/sysmodel/login/')
    if request.method == 'GET':
        c = {}
        usergroup = Group.objects.get(id = user_group_id)
        c.update(csrf(request))
        c.update({'MEDIA_URL' : settings.MEDIA_URL})
        c.update({'flexyclasses' : FlexyClass.objects.all().order_by('id')})
        c.update({'groups' : FlexyGroup.objects.all().order_by('seq', 'id')})
        c.update({'fields' : Field.objects.all().order_by('seq', 'id')})
        c.update({'ug' : usergroup})
        c.update({'usergroup_flexyclass' : 
                  UserGroup_FlexyClass.objects.filter(usergroup = usergroup)})
        c.update({'usergroup_field' : 
                  UserGroup_Field.objects.filter(usergroup = usergroup)})
        return render_to_response('sysmodel/usergroup/view.html', c)
    elif request.method == 'POST':
        dict = request.POST
        ug = Group.objects.get(id = user_group_id)
        for key in dict :
            if key == 'csrfmiddlewaretoken' :
                pass
            elif key[:3] == 'FLD' :
                UserGroup_Field.objects.set_perm(ug, key[4:], dict[key])
            elif key[:3] == 'CLS' :
                UserGroup_FlexyClass.objects.set_perm(ug, key[4:], dict[key])
        return HttpResponseRedirect('/sysmodel/usergroup/home/')